/*
 * Do form validation
 */
if (typeof HCM !== 'object') var HCM = {};

HCM.form = function(el) {
    var $root_el = $(el);
    var fields;
    var self = this;
    this.errors = new Array();
    this.customSubmitCall;
    this.errorsContainer;

    this.onReady = function() {
        // hide all panels.
        $root_el.find('.panel').hide();
        // only check the fields that need user to input or select value
        fields = $root_el.find('.field').filter(function(index) {
            return (!$(this).hasClass('text')
                || !$(this).hasClass('password')
                || !$(this).hasClass('email'));
        });
        self.errorsContainer = $root_el.find('.errorSummary');

        $root_el.find("form").submit(function(){
            self.errorsContainer.empty();
            self.errors.splice(0);
            if (self.customSubmitCall) {
                return self.customSubmitCall();
            } else 
                return submit();
        });
    };

    var submit = function() {
        var validate_result = self.validate();
        try {
            if (!validate_result) {
                self.errorsContainer.append('<ol></ol>');
                var errorList = self.errorsContainer.find('ol');
                for (var i=0; i < self.errors.length; i ++) {
                    errorList.append("<li>" + self.errors[i].message + "</li>");
                }
                self.errorsContainer.show();
            } else {
                self.errorsContainer.hide();
            }
        } catch (e) {
        // no exception dealment
        }
        return validate_result;
    };

    var removeStarCharacter = function(message) {
        var regExpr = /\*/;
        if (message) {
            message = message.replace(regExpr, '');
        }
        return message;
    };

    // if validate pass, return true;
    this.validate = function() {
        var has_error = false;

        try {
            for (var field_index = 0; field_index < fields.length; field_index++) {
                var field = $(fields[field_index]);

                // require validation
                if (field && field.hasClass('required')) {
                    if (field.hasClass('text') || field.hasClass('password') || field.hasClass('email')) {
                        var input_els = field.find('input');
                        for (var index = 0; (input_els && index < input_els.length); index++) {
                            has_error = !validateRequiredTextInput(field, input_els[index]) ? true : has_error;
                        }
                    } else if (field.has('select')) {
                        var select_el = field.find('select');
                        has_error = !validateRequiredSelect(field, select_el);
                    }
                }

                if (field && field.hasClass('password')) {
                    // validate password
                    input_els = field.find('input');
                    for (index = 0 ; (input_els && index < input_els.length); index++) {
                        has_error = !validatePasswordInput(field, input_els[index]) ? true : has_error;
                    }

                    if (!has_error && field.find('#confirmPassword').length == 1) {
                        has_error = !validateConfirmPassword(field);
                    }
                } else if (field && field.hasClass('email')) {
                    // validate email
                    var input_el = field.find('input');
                    has_error = !validateEmailInput(field, input_el);
                }
            }
        } catch(e) {
        // no exception dealment
        }
        return !has_error;
    };

    // if the field has been given value, return true.
    // field is a JQuery object.
    var validateRequiredTextInput = function(field, input_el) {
        if ($.trim($(input_el).val()) == '') {
            field.addClass('error');
            var errorMessage = new HCM.FormErrorMessage(input_el,
                removeStarCharacter(field.prev().text())+" can't be blank");
            self.errors.push(errorMessage);
            return false;
        } else {
            field.removeClass('error');
            return true;
        }
    };

    // if the specifed select has no value, return false.
    // field is a JQuery object.
    var validateRequiredSelect = function(field, select_el) {
        if ($.trim(select_el.val()) == '') {
            field.addClass('error');
            var errorMessage = new HCM.FormErrorMessage(select_el.get(0),
                removeStarCharacter("Must select a value for " + field.prev().text()));
            self.errors.push(errorMessage);
            return false;
        } else {
            field.removeClass('error');
            return true;
        }
    }

    // if password's length is less than 6 characters, it will return false.
    // and if the confirmed password doesn't match the password, also return false.
    // field is a JQuery object.
    var validatePasswordInput = function(field, input_el) {
        if ($(input_el).val().length < 6) {
            field.addClass('error');
            var errorMessage = new HCM.FormErrorMessage(input_el,
                removeStarCharacter("The length of "
                    + field.prev().text())
                + " must be longer than or equal to 6");
            self.errors.push(errorMessage);
            return false;
        }
        else {
            field.removeClass('error');
            return true;
        }
    };

    var validateConfirmPassword = function(field) {
        var confirm_password_el = field.find('#confirmPassword');
        if (!confirmPasswordValidate()) {
            field.addClass('error');
            var errorMessage = new HCM.FormErrorMessage(confirm_password_el.get(0),
                "The confirmed password must match the password");
            self.errors.push(errorMessage);
            return false;
        } else {
            return true;
        }
    };

    // if the field has been given the valid email, return true.
    // field is a JQuery object.
    var validateEmailInput = function(field, input_el) {
        if (!is_valid_email(input_el.val())) {
            field.addClass('error');
            var errorMessage = new HCM.FormErrorMessage(input_el,
                "Please use a valid email for " + removeStarCharacter(field.prev().text()));
            self.errors.push(errorMessage);
            return false;
        } else {
            field.removeClass('error');
            return true;
        }
    };

    var is_valid_email = function(email) {
        var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
        return reg.test(email);
    };

    // compare the password with the confirm password, if they are the same,
    // return true, otherwise return false.
    var confirmPasswordValidate = function() {
        var new_password_el = $root_el.find('#Password');
        var confirm_password_el = $root_el.find('#confirmPassword');
        if (new_password_el && confirm_password_el) {
            if (new_password_el.val() == confirm_password_el.val()) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    };

    this.onReady();
}

$(function() {
    $('div.form').each(function () {
        new HCM.form(this);
    });
});

// form error message class.
HCM.FormErrorMessage = function(el, message) {
    // the input/select/radio/checkbox .etc HTML element.
    this.field = el;
    // the error message for above element.
    this.message = message;
}